local lfs = require "lfs"
local M = {}

-- 设置文件存储根目录
M.root_path = "/www/uploads/"

-- 检查并创建目录
local function ensure_directory(path)
    if not lfs.attributes(path) then
        lfs.mkdir(path)
    end
end

-- 初始化
ensure_directory(M.root_path)

--[[
 * 生成文件名
 * @param string ext 文件扩展名
 * @param string prefix 前缀
 * @param string type 生成规则 (date, random, sequential)
 * @return string
--]]
M.buildSaveName = function(ext, prefix, type)
    prefix = prefix or ""
    type = type or "date"
    ext = ext or ""
    
    local filename
    if type == "date" then
        filename = os.date("%Y%m%d%H%M%S") .. "_" .. math.random(1000, 9999)
    elseif type == "random" then
        filename = tostring(math.random(1000000000, 9999999999))
    elseif type == "sequential" then
        -- 简单实现，实际应用中可能需要持久化计数器
        filename = tostring(os.time()) .. "_" .. math.random(1000, 9999)
    else
        filename = os.date("%Y%m%d%H%M%S") .. "_" .. math.random(1000, 9999)
    end
    
    return prefix .. filename .. (ext ~= "" and "." .. ext or "")
end

--[[
 * 检查文件是否存在
 * @param string filename 文件名
 * @return bool
--]]
M.fileExists = function(filename)
    return lfs.attributes(filename) ~= nil
end

--[[
 * 获取文件信息
 * @param string filepath 文件路径
 * @return table|nil
--]]
M.getFileInfo = function(filepath)
    local attr = lfs.attributes(filepath)
    if not attr then return nil end
    
    return {
        filename = filepath:match("([^/]+)$"),
        filepath = filepath,
        size = attr.size,
        mtime = attr.modification,
        ctime = attr.change,
        is_file = attr.mode == "file",
        is_dir = attr.mode == "directory"
    }
end

--[[
 * 创建目录
 * @param string dirpath 目录路径
 * @return bool
--]]
M.mkdir = function(dirpath)
    return lfs.mkdir(dirpath)
end

--[[
 * 删除文件
 * @param string filepath 文件路径
 * @return bool
--]]
M.unlink = function(filepath)
    if not M.fileExists(filepath) then return false end
    return os.remove(filepath)
end

--[[
 * 删除目录
 * @param string dirpath 目录路径
 * @return bool
--]]
M.rmdir = function(dirpath)
    if not M.fileExists(dirpath) then return false end
    return os.execute("rm -rf " .. dirpath) == 0
end

--[[
 * 文件上传
 * @param table file 上传的文件表(包含filename, content等)
 * @param string save_path 保存路径
 * @param string save_name 保存文件名
 * @return table|nil
--]]
M.upload = function(file, save_path, save_name)
    if not file or not file.content then return nil end
    
    save_path = save_path or ""
    save_name = save_name or file.filename
    
    -- 处理保存路径
    local full_path = M.root_path .. save_path
    ensure_directory(full_path)
    
    -- 处理文件名冲突
    local counter = 1
    local original_name = save_name
    while M.fileExists(full_path .. save_name) do
        local name, ext = original_name:match("^(.*)(%..+)$")
        if not name then
            name = original_name
            ext = ""
        end
        save_name = name .. "_" .. counter .. ext
        counter = counter + 1
    end
    
    -- 写入文件
    local file_handle, err = io.open(full_path .. save_name, "wb")
    if not file_handle then return nil, err end
    
    file_handle:write(file.content)
    file_handle:close()
    
    return {
        filename = save_name,
        filepath = full_path .. save_name,
        save_path = save_path,
        save_name = save_name,
        size = #file.content,
        ext = save_name:match("^.+(%..+)$") or ""
    }
end

--[[
 * 文件下载
 * @param string filepath 文件路径
 * @param string filename 下载显示的文件名
 * @return table|nil {content, size, filename}
--]]
M.download = function(filepath, filename)
    if not M.fileExists(filepath) then return nil end
    
    local file_handle = io.open(filepath, "rb")
    if not file_handle then return nil end
    
    local content = file_handle:read("*a")
    file_handle:close()
    
    filename = filename or filepath:match("([^/]+)$")
    
    return {
        content = content,
        size = #content,
        filename = filename
    }
end

--[[
 * 获取目录文件列表
 * @param string dirpath 目录路径
 * @return table
--]]
M.getFiles = function(dirpath)
    local files = {}
    
    for file in lfs.dir(dirpath) do
        if file ~= "." and file ~= ".." then
            local path = dirpath .. "/" .. file
            local attr = lfs.attributes(path)
            
            table.insert(files, {
                name = file,
                path = path,
                is_dir = attr.mode == "directory",
                size = attr.size,
                mtime = attr.modification
            })
        end
    end
    
    return files
end

--[[
 * 移动文件
 * @param string source 源文件路径
 * @param string dest 目标路径
 * @return bool
--]]
M.move = function(source, dest)
    if not M.fileExists(source) then return false end
    return os.rename(source, dest)
end

--[[
 * 复制文件
 * @param string source 源文件路径
 * @param string dest 目标路径
 * @return bool
--]]
M.copy = function(source, dest)
    if not M.fileExists(source) then return false end
    
    local src_file = io.open(source, "rb")
    if not src_file then return false end
    
    local dst_file = io.open(dest, "wb")
    if not dst_file then
        src_file:close()
        return false
    end
    
    dst_file:write(src_file:read("*a"))
    src_file:close()
    dst_file:close()
    
    return true
end

return M